const { exec } = require('child_process')
const fs = require('fs').promises
const path = require('path')
const { promisify } = require('util')
const execAsync = promisify(exec)
const axios = require('axios')
const logger = require('../utils/logger')
const { HTTP_STATUS, MESSAGE_ROLES } = require('../utils/constants')
const multer = require('multer')

class LessonPlanController {
  // 将doc文件转换为md文件
  static async convertDocToMd(req, res) {
    try {
      const { inputPath, outputPath } = req.body
      
      if (!inputPath || !outputPath) {
        return res.status(HTTP_STATUS.BAD_REQUEST).json({
          success: false,
          message: '输入路径和输出路径不能为空'
        })
      }

      // 检查输入文件是否存在
      try {
        await fs.access(inputPath)
      } catch (error) {
        return res.status(HTTP_STATUS.NOT_FOUND).json({
          success: false,
          message: '输入文件不存在'
        })
      }

      // 确保输出目录存在
      const outputDir = path.dirname(outputPath)
      await fs.mkdir(outputDir, { recursive: true })

      // 执行pandoc转换
      const command = `pandoc "${inputPath}" -o "${outputPath}"`
      logger.info(`执行pandoc命令: ${command}`)
      
      const { stdout, stderr } = await execAsync(command)
      
      if (stderr) {
        logger.warn(`Pandoc警告: ${stderr}`)
      }

      // 检查输出文件是否生成成功
      try {
        await fs.access(outputPath)
      } catch (error) {
        return res.status(HTTP_STATUS.INTERNAL_SERVER_ERROR).json({
          success: false,
          message: '文件转换失败，输出文件未生成'
        })
      }

      res.json({
        success: true,
        message: 'Doc文件已成功转换为Markdown',
        outputPath,
        stdout: stdout || '转换完成'
      })

    } catch (error) {
      logger.error('Doc转Md转换失败:', error)
      res.status(HTTP_STATUS.INTERNAL_SERVER_ERROR).json({
        success: false,
        message: '文件转换失败: ' + error.message
      })
    }
  }

  // 将md文件转换为doc文件
  static async convertMdToDoc(req, res) {
    try {
      const { inputPath, outputPath } = req.body
      
      if (!inputPath || !outputPath) {
        return res.status(HTTP_STATUS.BAD_REQUEST).json({
          success: false,
          message: '输入路径和输出路径不能为空'
        })
      }

      // 检查输入文件是否存在
      try {
        await fs.access(inputPath)
      } catch (error) {
        return res.status(HTTP_STATUS.NOT_FOUND).json({
          success: false,
          message: '输入文件不存在'
        })
      }

      // 确保输出目录存在
      const outputDir = path.dirname(outputPath)
      await fs.mkdir(outputDir, { recursive: true })

      // 执行pandoc转换
      const command = `pandoc "${inputPath}" -o "${outputPath}"`
      logger.info(`执行pandoc命令: ${command}`)
      
      const { stdout, stderr } = await execAsync(command)
      
      if (stderr) {
        logger.warn(`Pandoc警告: ${stderr}`)
      }

      // 检查输出文件是否生成成功
      try {
        await fs.access(outputPath)
      } catch (error) {
        return res.status(HTTP_STATUS.INTERNAL_SERVER_ERROR).json({
          success: false,
          message: '文件转换失败，输出文件未生成'
        })
      }

      res.json({
        success: true,
        message: 'Markdown文件已成功转换为Doc',
        outputPath,
        stdout: stdout || '转换完成'
      })

    } catch (error) {
      logger.error('Md转Doc转换失败:', error)
      res.status(HTTP_STATUS.INTERNAL_SERVER_ERROR).json({
        success: false,
        message: '文件转换失败: ' + error.message
      })
    }
  }

  // 将PPTX文件转换为MD文件
  static async convertPptxToMd(req, res) {
    try {
      const { inputPath, outputPath } = req.body
      
      if (!inputPath || !outputPath) {
        return res.status(HTTP_STATUS.BAD_REQUEST).json({
          success: false,
          message: '输入路径和输出路径不能为空'
        })
      }

      // 检查输入文件是否存在
      try {
        await fs.access(inputPath)
      } catch (error) {
        return res.status(HTTP_STATUS.NOT_FOUND).json({
          success: false,
          message: '输入文件不存在'
        })
      }

      // 确保输出目录存在
      const outputDir = path.dirname(outputPath)
      await fs.mkdir(outputDir, { recursive: true })

      // 使用pptx2md Python包进行转换
      // 注意：需要先安装 pip install pptx2md
      const { imageDir, disableImage, enableSlides } = req.body
      
      let command = `python -m pptx2md "${inputPath}" -o "${outputPath}"`
      
      // 添加可选参数
      if (imageDir) {
        command += ` -i "${imageDir}"`
      }
      if (disableImage) {
        command += ` --disable-image`
      }
      if (enableSlides) {
        command += ` --enable-slides`
      }
      
      logger.info(`执行pptx2md命令: ${command}`)
      
      const { stdout, stderr } = await execAsync(command)
      
      if (stderr) {
        logger.warn(`pptx2md警告: ${stderr}`)
      }

      // 检查输出文件是否生成成功
      try {
        await fs.access(outputPath)
      } catch (error) {
        return res.status(HTTP_STATUS.INTERNAL_SERVER_ERROR).json({
          success: false,
          message: 'PPTX文件转换失败，输出文件未生成'
        })
      }

      res.json({
        success: true,
        message: 'PPTX文件已成功转换为Markdown',
        outputPath,
        stdout: stdout || '转换完成'
      })

    } catch (error) {
      logger.error('PPTX转MD转换失败:', error)
      res.status(HTTP_STATUS.INTERNAL_SERVER_ERROR).json({
        success: false,
        message: 'PPTX文件转换失败: ' + error.message
      })
    }
  }

  // 读取文件内容
  static async readFile(req, res) {
    try {
      const { filePath } = req.body
      
      if (!filePath) {
        return res.status(HTTP_STATUS.BAD_REQUEST).json({
          success: false,
          message: '文件路径不能为空'
        })
      }

      // 检查文件是否存在
      try {
        await fs.access(filePath)
      } catch (error) {
        return res.status(HTTP_STATUS.NOT_FOUND).json({
          success: false,
          message: '文件不存在'
        })
      }

      // 读取文件内容
      const content = await fs.readFile(filePath, 'utf-8')
      
      res.json({
        success: true,
        content,
        filePath
      })

    } catch (error) {
      logger.error('读取文件失败:', error)
      res.status(HTTP_STATUS.INTERNAL_SERVER_ERROR).json({
        success: false,
        message: '读取文件失败: ' + error.message
      })
    }
  }

  // 写入文件内容
  static async writeFile(req, res) {
    try {
      const { filePath, content } = req.body
      
      if (!filePath || content === undefined) {
        return res.status(HTTP_STATUS.BAD_REQUEST).json({
          success: false,
          message: '文件路径和内容不能为空'
        })
      }

      // 确保目录存在
      const dir = path.dirname(filePath)
      await fs.mkdir(dir, { recursive: true })

      // 写入文件
      await fs.writeFile(filePath, content, 'utf-8')
      
      res.json({
        success: true,
        message: '文件写入成功',
        filePath
      })

    } catch (error) {
      logger.error('写入文件失败:', error)
      res.status(HTTP_STATUS.INTERNAL_SERVER_ERROR).json({
        success: false,
        message: '写入文件失败: ' + error.message
      })
    }
  }

  // 获取目录下的文件列表
  static async listFiles(req, res) {
    try {
      const { dirPath, extension } = req.query
      
      if (!dirPath) {
        return res.status(HTTP_STATUS.BAD_REQUEST).json({
          success: false,
          message: '目录路径不能为空'
        })
      }

      // 检查目录是否存在
      try {
        await fs.access(dirPath)
      } catch (error) {
        return res.status(HTTP_STATUS.NOT_FOUND).json({
          success: false,
          message: '目录不存在'
        })
      }

      // 读取目录内容
      const files = await fs.readdir(dirPath)
      
      // 过滤文件
      let filteredFiles = files
      if (extension) {
        filteredFiles = files.filter(file => file.endsWith(extension))
      }

      // 获取文件详细信息
      const fileDetails = await Promise.all(
        filteredFiles.map(async (file) => {
          const filePath = path.join(dirPath, file)
          const stats = await fs.stat(filePath)
          return {
            name: file,
            path: filePath,
            isDirectory: stats.isDirectory(),
            size: stats.size,
            modifiedTime: stats.mtime
          }
        })
      )
      
      res.json({
        success: true,
        files: fileDetails,
        dirPath
      })

    } catch (error) {
      logger.error('获取文件列表失败:', error)
      res.status(HTTP_STATUS.INTERNAL_SERVER_ERROR).json({
        success: false,
        message: '获取文件列表失败: ' + error.message
      })
    }
  }

  // 生成教案（调用LLM API）
  static async generateLessonPlan(req, res) {
    try {
      const { mdContent, templateContent, llmConfig } = req.body
      
      if (!mdContent || !templateContent || !llmConfig) {
        return res.status(HTTP_STATUS.BAD_REQUEST).json({
          success: false,
          message: 'Markdown内容、模板内容和LLM配置不能为空'
        })
      }

      // 构建教案生成的提示词
      const prompt = `请根据以下Markdown内容和模板，生成一份完整的教案：

## 原始内容：
${mdContent}

## 教案模板：
${templateContent}

## 要求：
1. 严格按照模板的格式和结构进行生成
2. 结合原始内容的知识点和要点
3. 确保教案内容完整、逻辑清晰
4. 教学目标要具体明确
5. 教学过程要详细可操作
6. 请直接输出教案内容，不要添加额外的说明文字

请生成教案：`

      // 构建消息格式
      const messages = [
        {
          role: MESSAGE_ROLES.SYSTEM,
          content: '你是一位专业的教育专家和教案设计师，擅长根据教学内容和模板生成高质量的教案。请严格按照用户提供的模板格式生成教案，确保内容专业、结构清晰、实用性强。'
        },
        {
          role: MESSAGE_ROLES.USER,
          content: prompt
        }
      ]

      // 调用AI服务生成教案
      logger.info('开始调用LLM API生成教案', { 
        model: llmConfig.model,
        contentLength: mdContent.length,
        templateLength: templateContent.length
      })

      // 调试：打印接收到的llmConfig
      logger.info('接收到的llmConfig:', JSON.stringify(llmConfig, null, 2))
      
      // 构建AI配置对象（兼容前端传递的配置格式）
      const aiConfig = {
        provider: llmConfig.provider,
        model: llmConfig.model,
        apiKey: llmConfig.apiKey,
        apiUrl: llmConfig.baseUrl,
        temperature: llmConfig.temperature || 0.7,
        maxTokens: llmConfig.maxTokens || 2000,
        topP: llmConfig.topP || 1.0,
        isActive: true
      }
      
      // 调试：打印构建的aiConfig
      logger.info('构建的aiConfig:', JSON.stringify(aiConfig, null, 2))

      // 直接调用AI API
      const aiResponse = await axios.post('http://localhost:806/api/ai/chat', {
        model: aiConfig.model || 'deepseek-chat',
        temperature: aiConfig.temperature || 0.7,
        max_tokens: aiConfig.maxTokens || 2000,
        apiKey: aiConfig.apiKey,
        apiUrl: aiConfig.apiUrl,
        messages: messages
      })

      if (!aiResponse.data.success) {
        throw new Error(aiResponse.data.message || 'AI API调用失败')
      }

      const response = {
        content: aiResponse.data.data.message,
        tokenUsage: aiResponse.data.data.usage
      }
      
      if (!response || !response.content) {
        throw new Error('LLM API返回的内容为空')
      }

      logger.info('教案生成成功', {
        model: llmConfig.model,
        responseLength: response.content.length,
        tokenUsage: response.tokenUsage
      })
      
      res.json({
        success: true,
        message: '教案生成成功',
        content: response.content,
        llmConfig,
        tokenUsage: response.tokenUsage
      })

    } catch (error) {
      logger.error('生成教案失败:', error)
      res.status(HTTP_STATUS.INTERNAL_SERVER_ERROR).json({
        success: false,
        message: '生成教案失败: ' + error.message
      })
    }
  }

  // 文件上传功能
  static async uploadFile(req, res) {
    try {
      const { targetPath } = req.body
      const file = req.file
      
      if (!file) {
        return res.status(HTTP_STATUS.BAD_REQUEST).json({
          success: false,
          message: '没有上传文件'
        })
      }
      
      if (!targetPath) {
        return res.status(HTTP_STATUS.BAD_REQUEST).json({
          success: false,
          message: '目标路径不能为空'
        })
      }
      
      // 确保目标目录存在
      const targetDir = path.dirname(targetPath)
      await fs.mkdir(targetDir, { recursive: true })
      
      // 将上传的文件移动到目标位置
      await fs.copyFile(file.path, targetPath)
      
      // 删除临时文件
      await fs.unlink(file.path)
      
      logger.info(`文件上传成功: ${targetPath}`)
      
      res.json({
        success: true,
        message: '文件上传成功',
        filePath: targetPath
      })
      
    } catch (error) {
      logger.error('文件上传失败:', error)
      res.status(HTTP_STATUS.INTERNAL_SERVER_ERROR).json({
        success: false,
        message: '文件上传失败',
        error: error.message
      })
    }
  }

  // 生成输出路径
  static generateOutputPath(inputPath, newExtension) {
    const dir = path.dirname(inputPath)
    const name = path.basename(inputPath, path.extname(inputPath))
    return path.join(dir, `${name}.${newExtension}`)
  }
}

module.exports = LessonPlanController